package com.googlecode.groovy_toy_orm

import com.googlecode.groovy_toy_orm.internal.Util
import groovy.sql.Sql

import static Util.lastToken

/**
 * @author: DavydovMD
 * Date: 05.04.13
 * Time: 13:06
 */
class SingleDbTableMapper<T> extends TableMapper implements DbSourced {
    Closure<Sql> dbGetter
    Class<T> beanClass


    @Delegate
    Unmarshaller<T> unmarshaller

    SingleDbTableMapper(Mapper mapper, Closure<Sql> dbGetter, String tableName, String keyField = null, Class beanClass = HashMap.class) {
        super(mapper, tableName, keyField)
        this.dbGetter = dbGetter
        this.beanClass = beanClass
        this.unmarshaller = new Unmarshaller(this, beanClass)
    }

    SingleDbTableMapper(MapperFields builder, Closure<Sql> dbGetter, String tableName, String keyField = null, Class beanClass = HashMap.class) {
        super(builder, tableName, keyField)
        this.dbGetter = dbGetter
        this.beanClass = beanClass
        this.unmarshaller = new Unmarshaller(this, beanClass)
    }



    @Lazy
    String dbUrl = { (SqlMappingUtil.getDbUrl(dbGetter())) }()




    public String getPrefix() {
        "${lastToken(beanClass.getName())}.$tableName."
    }

    public Map fromDbFirstRowAsMap(def value, String fieldName = keyField) {
        Map ret = SqlMappingUtil.simpleSelectFirstRowAsMap(dbGetter(), tableName, this, fieldName, value)
        if (!ret) throw new NoSuchFieldError("No data found for query [${fieldName} = ${value}]")
        this.transformMap(ret)
    }



    public String getFqTableName() {
        tableName.contains("[") ? tableName : "\"${tableName}\""
    }

    public String getShortTableName() {
        if (tableName.contains("["))
            "\"${lastToken(tableName)}\""
        else
            "\"$tableName\""
    }

    @Override
    public String getFqSourceName(String field) {
        List from = getField(field).from
        if (from.size() != 1) return null
        "${shortTableName}.\"${from.last()}\""
    }

    @Override
    public Map<String, String> getFqSourceNames(String field) {
        Map ret = [:]
        builder.getField(field).from.each { String s ->
            ret.put(s, "${shortTableName}.\"${s}\"")
        }
        ret
    }


    public String getAllFieldsListClause() {
        this.builder.mappedFields().join(',')
    }

}





